﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Pay.DTO;
using Pay.DTO.htl;
using Pay.IService;
using Pay.Core;
using System.Text;
using Pay.TO;
using System.Linq;

namespace Pay.Service {
    public class HtlMallService : ServiceBase, IHtlMallService, IDisposable {
        private IUnitOfWork _iUnitOfWork;
        private IPayHtmlService _iPayhtmlService;
        private IMerchantService _iMerchantService;
        private IProductService _iProductService;
        private IOrderService _iOrderService;
        private HtlMallSign _htlSign;
        public HtlMallService(IUnitOfWork iUnitOfWork, IPayHtmlService iPayhtmlService,
                              IMerchantService iMerchantService, IProductService iProductService,
                              IOrderService iOrderService) : base(iUnitOfWork) {
            _iUnitOfWork = iUnitOfWork;
            _iPayhtmlService = iPayhtmlService;
            _htlSign = new HtlMallSign();
            _iMerchantService = iMerchantService;
            _iProductService = iProductService;
            _iOrderService = iOrderService;
        }
        /// <summary>
        /// 运费查询
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<express_list> GetFreight(htl_freight_req model) {
            var freight = await _htlSign.HtlReq<htl_freight_res>(model, "/express/getExpress");
            return freight.express_list;
        }
        /// <summary>
        /// 订单查询
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<orders_info> GetOrdersInfo(htl_order_search_req model) {
            var order = await _htlSign.HtlReq<htl_order_search_res>(model, "/order/getOrders");
            return order.orders_info;
        }
        /// <summary>
        /// 商品数据查询
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<products_list> GetProducts(htl_product_search_req model) {
            var product = await _htlSign.HtlReq<htl_product_search_res>(model, "/product/search");
            return product.products_list;
        }
        /// <summary>
        /// 货运方式查询
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public async Task<shipping_method_info> GetShippingInfo(htl_req_base req) {
            var shipping_method = await _htlSign.HtlReq<htl_shipping_res>(req, "/shipping/get_shipping_method");
            return shipping_method.shipping_method_info;
        }
        /// <summary>
        /// 仓储费查询
        /// </summary>
        /// <param name="store_expenses"></param>
        /// <returns></returns>
        public async Task<store_expenses_list> GetStoreExpenses(htl_store_expenses_req store_expenses) {
            var store = await _htlSign.HtlReq<htl_store_expenses_res>(store_expenses, "/express/getStoreExpenses");
            return store.store_expenses_list;
        }
        /// <summary>
        /// 订单取消
        /// </summary>
        /// <param name="orderNo"></param>
        /// <param name="remark"></param>
        /// <returns></returns>
        public async Task<htl_res_base> OrderCancel(string orderNo,string remark) {
            var orders = new orders_cancel_info {
                 order=new List<htl_order_cancel> {
                     new htl_order_cancel{
                         custom_orders_number=orderNo,
                         remark =remark
                     }
                 }
            };
            var model = new htl_order_cancel_req {
                orders_info = XmlHelper.XmlSerialize(orders, Encoding.UTF8, false)
            };
            var order = await _htlSign.HtlReq<htl_res_base>(model, "/order/cancelOrder");
            return order;
        }
        /// <summary>
        /// 同步商品数据
        /// </summary>
        /// <param name="htl_product"></param>
        /// <returns></returns>
        public string PullProduct(htl_product_req htl_product) {
            var log = IocHelper.Get<ILogHelper>("info");
            bool is_verify = false;
            is_verify = _htlSign.VerifySign(htl_product);
            if (!is_verify)
                return _htlSign.VerifyFail("验签失败");
            if (string.IsNullOrEmpty(htl_product.products_xml))
                return _htlSign.VerifyFail("同步商品xml数据异常");
            try {
                var products_list = XmlHelper.XmlDeserialize<products_list>(htl_product.products_xml, Encoding.UTF8);
                foreach (var product in products_list.product) {
                    var p = context.Products.FirstOrDefault(c => c.Sku == product.sku && c.IsHtl == 1);
                    //修改
                    if (p != null) {
                        p.Sku = product.sku;
                        p.Name = product.products_name;
                        p.MaxQuantity = product.max_quantity;
                        p.MainImageUrl = product.main_image_url;
                        p.MinQuantity = product.min_quantity;
                        p.AgentPrices = product.agent_prices.ToJson();
                        p.Stock = product.quantity;
                        p.Weight = (double)product.weight;
                        p.SaleStatus = product.status == 1 ? SaleStatus.Sell : SaleStatus.OutOfStock;
                        if (p.SaleStatus == SaleStatus.OutOfStock)
                            p.Code = "0000";
                        if (product.agent_prices.agent_price.Count > 0) {
                            if (p.CostPrice < product.agent_prices.agent_price.First().price) {
                                p.SaleStatus = SaleStatus.OutOfStock;
                                p.Code = "0001";
                            }
                        }
                        if (product.quantity == 0) {
                            p.SaleStatus = SaleStatus.OutOfStock;
                            p.Code = "0002";
                        }
                    }
                }
            } catch (Exception ex) {
                log.Info(ex.InnerException.Message);
                log.Info(htl_product.products_xml);
                return _htlSign.VerifyFail("xml数据异常");
            }

            var orderNo = string.Format("P{0}", DtoHelper.GenerateOrderNumber());
            var pay_html = new pay_html_dto {
                html = htl_product.products_xml,
                charge = htl_product.alliance_code,
                merchant_no = RequestMethod.HTL_NO,
                create_time = DateTime.Now,
                order_no = orderNo,
                pay_type = "3",
                is_finish = 0,
                id = orderNo
            };
            is_verify = _iPayhtmlService.Save(pay_html);
            if (!is_verify)
                return _htlSign.VerifyFail("合作商业务异常");

            return _htlSign.VerifySuccess();
        }
        /// <summary>
        /// 解析推送商品xml数据
        /// </summary>
        public void AnalysisProducts() {
            var log = IocHelper.Get<ILogHelper>("info");
            log.Info("海淘乐业务处理中...");
            var pay_htmls = _iPayhtmlService.GetPayHtmls(RequestMethod.TOKEN_HTML_PRODUCT);
            foreach (var pay_html in pay_htmls) {
                var products = new List<Data.Product>();
                var cy = new List<Data.Product>();
                var merchant = _iMerchantService.Get(pay_html.merchant_no);
                try {
                    var products_list = pay_html.html.ToXmlObject<products_list>();
                    var ps = new List<product>();
                    var distinctProducts = products_list.product.GroupBy(c=>c.sku).Where(c=>c.Count()>1);
                    foreach (var p in distinctProducts) {
                        var item = p.ToList().Last();
                        ps.Add(item);
                        products_list.product.RemoveAll(c=>c.sku == item.sku);
                    }
                    if (ps.Count > 0)
                        products_list.product.AddRange(ps);
                    
                    foreach (var product in products_list.product) {
                        bool has_data = context.Products.Any(c => c.Sku == product.sku && c.IsHtl == 1);
                        if (!has_data) {
                            //新增
                            var model = product.ToDtoObject<Data.Product>();
                            model.MerchantId = merchant.id;
                            model.AgentPrices = product.agent_prices.ToJson();
                            model.CostPrice = (product.agent_prices.agent_price.Count > 0 ? product.agent_prices.agent_price.First().price : 0);
                            model.ImagePath = product.image_url.Contains("|") ? product.image_url.Split('|').ToJson() : "[]";
                            model.SaleStatus = product.status == 1 ? SaleStatus.Sell : SaleStatus.OutOfStock;
                            model.AuditStatus = AuditStatus.PendingAudit;
                            model.IsHtl = 1;
                            model.CreateTime = DateTime.Now.ToUnix();
                            model.UpdateTime = DateTime.Now.ToUnix();
                            products.Add(model);
                        }
                    }
                    context.Products.AddRange(products);
                    var html = context.PayHtmls.FirstOrDefault(c => c.Id == pay_html.id);
                    html.IsFinish = 1;
                    int result = _iUnitOfWork.Commit();
                    log.Info("海淘乐业务处理完成...");
                } catch (Exception ex) {
                    string error_msg = (ex.InnerException == null ? ex.Message : ex.InnerException.Message);
                    log.Info(string.Format("xml解析异常：{0}", error_msg));
                }
            }
        }
        /// <summary>
        /// 推送订单
        /// </summary>
        /// <returns></returns>
        public async Task<int> PushOrder() {
            var log = IocHelper.Get<ILogHelper>("info");
            log.Info("海淘乐订单推送中...");
            int result = 0;
            var channel = new channel();
            var pay_htmls = _iPayhtmlService.GetPayHtmls(RequestMethod.TOKEN_HTML_ORDER);
            foreach (var pay_html in pay_htmls) {
                var ord_html = pay_html.html.ToObject<order_dto>();
                var products = new order_produts();
                var order_shipping_info = new order_shipping_info {
                    shipping_info = new List<shipping_info> {
                         new shipping_info{
                               shipping_customers_identity = ord_html.shipping.id_card,
                               shipping_customers_identity_name = ord_html.shipping.real_name,
                               shipping_customers_name = ord_html.shipping.ship_to,
                               shipping_telephone = ord_html.shipping.phone
                         }
                     }
                };
                channel.item = new htl_order();
                channel.item.custom_orders_number = pay_html.order_no;
                channel.item.order_shipping_info = order_shipping_info;
                var regions = ord_html.shipping.region_name.Split(' ');
                decimal agentPrice = 0;
                int end_quantity = 0;
                bool is_error = false;
                channel.item.shipping_address = ord_html.shipping.address;
                channel.item.shipping_province = regions[0];
                channel.item.shipping_city = regions[1];
                channel.item.shipping_district = (regions.Length == 3 ? regions[2] : "");
                var order_items = ord_html.order_items;
                foreach (var order_item in order_items) {
                    var product = _iProductService.Get(order_item.product_id);
                    agentPrice = product.cost_price.Value;
                    if (ord_html.pay_amount < agentPrice) {
                        is_error = true;
                        break;
                    }
                    if (!string.IsNullOrEmpty(product.agent_prices)) {
                        var prices = product.agent_prices.ToObject<agent_prices>();
                        foreach (var c in prices.agent_price) {
                            if (!string.IsNullOrEmpty(c.end_quantity)) {
                                end_quantity = int.Parse(c.end_quantity);
                                if (order_item.quantity >= c.start_quantity && order_item.quantity <= end_quantity) {
                                    agentPrice = c.price;
                                    break;
                                }
                            } else {
                                if (order_item.quantity >= c.start_quantity) {
                                    agentPrice = c.price;
                                }
                            }
                        }
                    }
                    products.product.Add(new order_product {
                        sku = product.sku,
                        sales_price = agentPrice,
                        products_qty = order_item.quantity
                    });
                    if (string.IsNullOrEmpty(product.sku))
                        is_error = true;
                }
                if (is_error) continue;
                channel.item.order_products = products;
                var model = new htl_order_req {
                    order = XmlHelper.XmlSerialize(channel, Encoding.UTF8, false)
                };
                var html = context.PayHtmls.FirstOrDefault(c => c.OrderNo == pay_html.order_no);
                var push_order = context.Orders.FirstOrDefault(c => c.OrderNo == pay_html.order_no);
                var order = await _htlSign.HtlReq<htl_order_res>(model, "/order/standard_accept_order");
                if (order.status == 200) {
                    log.Info(string.Format("订单：{0}推送成功", ord_html.order_no));
                    html.IsFinish = 1;
                    push_order.PushStatus = OrderPushStatus.Pushed;
                } else {
                    push_order.PushStatus = OrderPushStatus.PushFail;
                    push_order.PushFailMsg = order.message;
                    html.IsFinish = 2;
                    html.Charge = string.Format("订单：{0}推送失败，原因：{1}", ord_html.order_no, order.message);
                }
                result = _iUnitOfWork.Commit("PayHtml");
                log.Info(string.Format("订单：{0}推送失败", ord_html.order_no));
                log.Info(order.ToJson());
            }
            return result;
        }

        public async Task<int> PushOrderData(string order_no) {
            decimal agentPrice = 0;
            int end_quantity = 0;
            bool is_error = false;
            var order = _iOrderService.Get(order_no);
            var channel = new channel();
            var products = new order_produts();
            var order_shipping_info = new order_shipping_info {
                shipping_info = new List<shipping_info> {
                         new shipping_info{
                               shipping_customers_identity = order.shipping.id_card,
                               shipping_customers_identity_name = order.shipping.real_name,
                               shipping_customers_name = order.shipping.ship_to,
                               shipping_telephone = order.shipping.phone
                         }
                     }
            };
            channel.item = new htl_order();
            channel.item.custom_orders_number = order_no;
            channel.item.order_shipping_info = order_shipping_info;
            var regions = order.shipping.region_name.Split(' ');
            channel.item.shipping_address = order.shipping.address;
            channel.item.shipping_province = regions[0];
            channel.item.shipping_city = regions[1];
            channel.item.shipping_district = (regions.Length == 3 ? regions[2] : "");
            foreach (var order_item in order.order_items) {
                var product = _iProductService.Get(order_item.product_id);
                agentPrice = product.cost_price.Value;
                if (order.pay_amount < agentPrice) {
                    is_error = true;
                    break;
                }
                if (!string.IsNullOrEmpty(product.agent_prices)) {
                    var prices = product.agent_prices.ToObject<agent_prices>();
                    foreach (var c in prices.agent_price) {
                        if (!string.IsNullOrEmpty(c.end_quantity)) {
                            end_quantity = int.Parse(c.end_quantity);
                            if (order_item.quantity >= c.start_quantity && order_item.quantity <= end_quantity) {
                                agentPrice = c.price;
                                break;
                            }
                        } else {
                            if (order_item.quantity >= c.start_quantity) {
                                agentPrice = c.price;
                            }
                        }
                    }
                }
                products.product.Add(new order_product {
                    sku = product.sku,
                    sales_price = agentPrice,
                    products_qty = order_item.quantity
                });
            }
            if (is_error) return 0;
            channel.item.order_products = products;
            var model = new htl_order_req {
                order = XmlHelper.XmlSerialize(channel, Encoding.UTF8, false)
            };
            var order_result = await _htlSign.HtlReq<htl_order_res>(model, "/order/standard_accept_order");
            if (order_result.status == 200) {

            }

            return 0;
        }
        /// <summary>
        /// 订单状态查询
        /// </summary>
        /// <returns></returns>
        public async Task<string> GetOrderStatus() {
            var log = IocHelper.Get<ILogHelper>("info");
            string result = "ok";
            var merchant = _iMerchantService.Get(RequestMethod.HTL_NO);
            var query = new OrderQuery {
                merchant_id = merchant.id,
                order_status = OrderStatus.WaitDelivery,
                order_type = 1
            };
            var orders_info = new order_status_info();
            var orders = _iOrderService.Gets(query);
            var ordersNo = orders.Select(c => c.OrderNo).ToList();
            foreach (var orderNo in ordersNo) {
                orders_info.order.Add(new order_status {
                    custom_orders_number = orderNo
                });
                var model = new htl_orders_info_req {
                    orders_info = XmlHelper.XmlSerialize(orders_info, Encoding.UTF8, false)
                };
                var api_result = await _htlSign.HtlReq<htl_orders_info_res>(model, "/order/getOrderStatus");
                log.Info(api_result.ToJson());
                if (api_result.status == 200) {
                    result = _iOrderService.UpdateShipping(api_result);
                }
                orders_info.order.Clear();
            }
            return result;
        }
        /// <summary>
        /// 物流查询
        /// </summary>
        /// <returns></returns>
        public async Task<htl_logistics_res> GetLogistics(string orderNo) {
            var orders_info = new order_status_info();
            orders_info.order.Add(new order_status {
                custom_orders_number = orderNo
            });
            var model = new htl_logistics_req {
                orders_info = XmlHelper.XmlSerialize(orders_info, Encoding.UTF8, false)
            };
            var logistics = await _htlSign.HtlReq<htl_logistics_res>(model, "/shipping/get_multi_shipping");
            return logistics;
        }

        public int UpdateCostPrice() {
            var products = context.Products.GroupBy(c=>c.Sku).Where(c=>c.Count()>1).ToList();
            foreach (var item in products) {
                item.ToList();
            }
            return 0;
        }
    }
}
